<template>
  <div class="bound-goods">
    <div
      v-if="!Disabled"
      class="classification selected el-cascader-panel is-bordered"
    >
      <!-- 店铺筛选 -->
      <SubMchList v-model="selSubMchList" />

      <!-- 分类筛选 -->
      <CategoryTree
        v-model="selCategoryTree"
        :subMchList="selSubMchList"
        :productName.sync="productName"
      />

      <!-- 待选商品列表 -->
      <div class="product-list">
        <h5>
          商品列表
          <template v-if="goodsList.length > 0">
            （{{ goodsList.length }}）
          </template>
          <span v-if="goodsList.length > 0" @click="allSelectClick">
            <el-checkbox v-model="allSelect">全选</el-checkbox>
          </span>
        </h5>
        <el-scrollbar v-if="goodsList.length > 0" v-loading="loading">
          <div
            v-for="(item, index) in goodsList"
            :key="item.productId"
            class="el-cascader-node selected-item"
          >
            <span class="el-cascader-node__label">
              <el-checkbox
                v-model="item.checked"
                @change="goodsListChange(index)"
              >
                {{ item.productName }}
              </el-checkbox>
            </span>
          </div>
        </el-scrollbar>
        <p v-else class="tips">
          <i class="el-icon-s-order"></i>
          请选择左侧分类
        </p>
      </div>
    </div>
    <div
      class="selected el-cascader-panel is-bordered"
      :style="{
        width: Disabled ? '100%' : 'calc(30% - 10px)',
        marginLeft: Disabled ? '0' : '10px'
      }"
    >
      <div>
        <h5>
          已绑定商品
          <template v-if="selectedList.length > 0">
            （{{ selectedList.length }}）
          </template>
          <el-popconfirm
            v-if="selectedList.length > 0 && !Disabled"
            title="您确定要移除全部吗？"
            style="float: right; margin-right: 10px"
            @confirm="removeAll"
          >
            <el-button slot="reference" size="mini">移除全部</el-button>
          </el-popconfirm>
        </h5>
        <el-scrollbar v-if="selectedList.length > 0" v-loading="parductLoading">
          <draggable
            v-model="selectedList"
            :disabled="Disabled"
            group="site"
            animation="300"
          >
            <div
              v-for="(item, index) in selectedList"
              :key="item.productId"
              class="el-cascader-node selected-item"
            >
              <span class="el-cascader-node__label">
                {{ item.productName }}
              </span>
              <i
                v-if="!Disabled"
                @click="deleteProduct(item, index)"
                class="el-icon-circle-close"
              ></i>
            </div>
          </draggable>
        </el-scrollbar>
        <p v-else class="tips">
          <i class="el-icon-s-order"></i>
          至少绑定一个商品
        </p>
      </div>
    </div>
  </div>
</template>
<script>
import SubMchList from './SubMchList'
import CategoryTree from './CategoryTree'
import draggable from 'vuedraggable'
let timer = null
export default {
  name: 'BoundGoods',
  components: { SubMchList, CategoryTree, draggable },
  inject: {
    elForm: {
      default: ''
    }
  },
  props: {
    value: null,
    disabled: {
      type: Boolean,
      default: false
    },
    // 如果是一个对象，必传此参数
    dataKey: {
      default: ''
    },
    // 获取商品表单参数
    param: {
      type: Object,
      default () {
        return {}
      }
    }
  },
  data () {
    return {
      loading: false,
      parductLoading: false,
      selectedList: [], // 已选择商品
      goodsList: [], // 待选择商品列表
      allSelect: false,
      selCategoryTree: [], // 分类列表
      selSubMchList: [],
      productName: ''
    }
  },
  computed: {
    Disabled () {
      return this.disabled || (this.elForm || {}).disabled
    }
  },
  watch: {
    value: {
      handler (n) {
        // 传进来的数据，如果已选择列表里面没有，就去后台请求
        if (Array.isArray(n)) {
          this.getSelectProducts(n)
        }
      },
      deep: true,
      immediate: true
    },
    // 分类改变
    selCategoryTree: {
      handler (n) {
        this.getProductList()
      },
      deep: true
    },
    productName: {
      handler (n) {
        this.getProductList()
      },
      deep: true
    },
    goodsList: {
      handler (n) {
        // 计算全选反选
        this.allSelect =
          this.goodsList.length > 0
            ? this.goodsList.every(item => item.checked)
            : false
      },
      deep: true
    },
    selectedList: {
      handler (n) {
        this.$emit(
          'input',
          n.map(item => {
            if (this.dataKey) {
              return { [this.dataKey]: item.productId }
            } else {
              return item.productId
            }
          })
        )
        this.$parent.$nextTick(() => {
          this.$parent.$emit('el.form.blur', n) // 触发父组件表单校验
        })
      },
      deep: true
    }
  },
  methods: {
    // 获取传入的数据回显
    getSelectProducts (productIds) {
      let ids = []
      // 筛选当前列表不存在的id
      productIds.forEach(item => {
        let id = this.dataKey ? item[this.dataKey] : item // 传进来的id
        if (!this.selectedList.some(_ => _.productId === id)) {
          ids.push(id)
        }
      })

      if (ids.length == 0) return

      this.parductLoading = true
      this.$POST('sot-admin-api/product/base/queryProductListNoPermission', {
        ids: ids
      })
        .then(res => {
          if (res.errorCode === '00000') {
            res.data?.forEach(_ => {
              this.selectedList.push({
                checked: true,
                productId: _.id,
                productName: _.name
              })
            })
            this.productListInif()
          }
        })
        .finally(_ => {
          this.parductLoading = false
        })
    },
    // 获取商品
    getProductList () {
      clearTimeout(timer)
      timer = setTimeout(() => {
        this.loading = true
        this.$POST('sot-admin-api/product/base/queryProductListAndTotal', {
          categoryIds: this.selCategoryTree,
          subMchIds: this.selSubMchList,
          name: this.productName,
          ...this.param
        })
          .then(res => {
            if (res.errorCode === '00000') {
              this.goodsList = res.data?.list.map(_ => {
                return {
                  checked: false,
                  productId: _.id,
                  productName: _.name
                }
              })
              if (this.goodsList.length > 300) {
                this.goodsList.length = 300 // 如果超出300个，只渲染300个
              }
              this.productListInif()
            }
          })
          .finally(_ => {
            this.loading = false
          })
      }, 500)
    },

    // 处理商品列表初始化
    productListInif () {
      // 商品列表变化的时候，需要计算那些是被选中过的
      this.goodsList.forEach(item => {
        item.checked = false
        this.selectedList.forEach(item2 => {
          if (item.productId == item2.productId) {
            item.checked = true
          }
        })
      })
    },

    allSelectClick () {
      clearTimeout(timer) // 解决由于内部冒泡会导致触发两次的问题
      timer = setTimeout(() => {
        this.goodsList.forEach((item, index) => {
          item.checked = this.allSelect // 全选反选
          this.goodsListChange(index)
        })
      }, 10)
    },

    // 商品列表被点击,移除或添加到已绑定商品
    goodsListChange (index) {
      let goods = this.goodsList[index]
      let exist = -1

      // 先检测需要变更的节点在已绑定列表中存不存在
      this.selectedList.forEach((item, index) => {
        if (item.productId == goods.productId) {
          exist = index // 存在
        }
      })

      if (goods.checked && exist === -1) {
        this.selectedList.unshift(goods) // 商品列表选中且未存在与已绑定，添加
      }
      if (!goods.checked && exist !== -1) {
        this.deleteProduct(goods, exist) // 商品列表取消且已存在与已绑定，删除
      }
    },

    // 移除全部已绑定商品
    removeAll () {
      this.selectedList = []
      this.productListInif()
    },

    // 移除已绑定商品
    deleteProduct (product, index) {
      this.selectedList.splice(index, 1)
      // 移除的时候需要判断在不在商品列表中，在的话取消选择
      this.goodsList.forEach(item => {
        if (item.productId == product.productId) {
          item.checked = false
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
.bound-goods {
  height: 442px;
  :deep(.selected) {
    display: inline-block;
    width: calc(30% - 10px);
    height: 100%;
    margin-left: 10px;
    float: left;
    h5 {
      font-size: 14px;
      margin: 0;
      height: 36px;
      line-height: 36px;
      padding-left: 10px;
      background: #efefef;
      .el-checkbox {
        float: right;
        padding-right: 10px;
      }
    }
    .el-scrollbar {
      height: calc(440px - 36px);
    }

    .tips {
      text-align: center;
      color: #ccc;
      padding-top: 100px;
      i {
        display: block;
        font-size: 60px;
      }
    }
  }
  :deep(.classification) {
    width: calc(70%);
    margin-left: 0;
    & > div {
      display: inline-block;
      width: 30%;
      float: left;
      &.sub-mch-list,
      &.category-tree {
        .el-scrollbar {
          height: calc(440px - 96px);
        }
      }
    }
    .el-scrollbar {
      height: calc(440px - 36px);
    }
  }

  :deep(.el-scrollbar__wrap) {
    overflow-x: hidden;
  }
  :deep(.el-cascader-node) {
    padding: 0;
    padding-right: 20px;
  }

  // 覆盖全局样式
  :deep(.product-list) {
    width: 40% !important;
    .el-checkbox {
      width: auto;
      height: auto;
      position: static;
    }
    .el-checkbox .el-checkbox__input {
      position: static;
    }
    .el-checkbox__label {
      padding-left: 5px;
    }
  }

  :deep(.search-tree) {
    .el-tree-node__expand-icon.is-leaf {
      color: #c0c4cc;
    }
  }
}
</style>
